/* Zatok - язык программирования текстовых игр
 * (С) 2010 - 2012 Меркулов Матвей Юрьевич
 * Код лицензирован под лицензией GNU LGPL
 * Вы можете прочитать текст лицензии по адресу:
 * http://www.gnu.org/copyleft/lesser.html
 * или прочитать русский перевод по адресу:
 * http://ru.wikisource.org/wiki/GNU_Lesser_General_Public_License
 */

package base.function.operator;

import base.function.CFunction;
import base.value.CArrayValue;
import base.value.CFloatValue;
import base.value.CIntValue;
import base.value.CStringValue;
import base.value.CValue.CType;
import base.value.CValue;

public class CAdd extends CFunction {
	private CIntValue ReturnedIntValue = new CIntValue( 0 );
	private CFloatValue ReturnedFloatValue = new CFloatValue( 0f );
	private CStringValue ReturnedStringValue = new CStringValue( "");
	private CArrayValue ReturnedArrayValue = new CArrayValue();

	
	
	@Override
	public void Init() {
		AssertParam( 2 );
	}
	
	
	
	@Override
	public CValue GetValue() {
		CValue Value0 = Param[ 0 ].GetValue();
		CValue Value1 = Param[ 1 ].GetValue();
		switch( GetType( Value0, Value1 ) ) {
			case Array:			
				ReturnedArrayValue.Values = ToArray();
				return ReturnedArrayValue;
			case String:
				ReturnedStringValue.Value = ToString();
				return ReturnedStringValue;
			case Float:
				ReturnedFloatValue.Value = ToFloat();
				return ReturnedFloatValue;
			default:
				ReturnedIntValue.Value = ToInt();
				return ReturnedIntValue;
		}
	}
	
	
	
	public CType GetType( CValue Value0, CValue Value1 ) {
		CType Type0 = Value0.GetType();
		CType Type1 = Value1.GetType();
		if ( Type0 == CType.String || Type1 == CType.String ) return CType.String;
		if ( Type0 == CType.Array || Type1 == CType.Array ) return CType.Array;
		if ( Type0 == CType.Float || Type1 == CType.Float ) return CType.Float;
		if ( Type0 == CType.Int && Type1 == CType.Int ) return CType.Int;
		Error( "Параметры функции должны быть числовыми" );
		return null;
	}

	
	
	@Override
	public int ToInt() {
		CValue Value0 = Param[ 0 ].GetValue();
		CValue Value1 = Param[ 1 ].GetValue();
		switch( GetType( Value0, Value1 ) ) {
			case Array:
				Error( "Массивы нельзя использовать в операциях с числами" );
				return 0;
			case String:
				return Integer.valueOf( Value0.ToString() + Value1.ToString() );
			case Float:
				return ( int ) ( Value0.ToFloat() + Value1.ToFloat() );
			default:
				return Value0.ToInt() + Value1.ToInt();
		}
	}



	@Override
	public float ToFloat() {
		CValue Value0 = Param[ 0 ].GetValue();
		CValue Value1 = Param[ 1 ].GetValue();
		switch( GetType( Value0, Value1 ) ) {
			case Array:
				Error( "Массивы нельзя использовать в операциях с числами" );
				return 0f;
			case String:
				return Float.valueOf( Value0.ToString() + Value1.ToString() );
			case Float:
				return Value0.ToFloat() + Value1.ToFloat();
			default:
				return (float) Value0.ToInt() + Value1.ToInt();
		}
	}
	
	

	@Override
	public String ToString() {
		CValue Value0 = Param[ 0 ].GetValue();
		CValue Value1 = Param[ 1 ].GetValue();
		switch( GetType( Value0, Value1 ) ) {
			case Array:
				ReturnedArrayValue.Values = CArrayValue.JoinArrays( Value0.ToArray(), Value1.ToArray() );
				return ReturnedArrayValue.ToString();
			case String:
				return Value0.ToString() + Value1.ToString();
			case Float:
				return String.valueOf( Value0.ToFloat() + Value1.ToFloat() );
			default:
				return String.valueOf( Value0.ToInt() + Value1.ToInt() );
		}
	}
	
	
	
	@Override
	public CValue[] ToArray() {
		return CArrayValue.JoinArrays( Param[ 0 ].GetValue().ToArray(), Param[ 1 ].GetValue().ToArray() );
	}
}
